/*
 * Copyright (C) 2009 AnK Team
 *	 Andrey Korolev
 *	 Anna Krel
 *	 Anna Kapanina
 *	 
 *	 http://code.google.com/p/ankfood/	
 *    
     
 *    Licensed under the GNU General Public License, Version 2.0 (the "License");
 *
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *         http://www.gnu.org/licenses/gpl-2.0.html

 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,

 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */



package org.ank.food;



import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

import com.sadko.about.AboutActivity;

public class MenuActivity extends Activity implements Runnable{
	
//	private static final int MENU_ITEM_VIEW_VALUES = Menu.FIRST;
	private static final int MENU_ITEM_CLEAR = Menu.FIRST;
	private static final int MENU_ITEM_EDIT_PROFILE = Menu.FIRST+1;
	private static final int MENU_ITEM_ABOUT= Menu.FIRST+2;
//	private static final int MENU_ITEM_HELP = Menu.FIRST+3;
	private static final int MENU_ITEM_DELETE = Menu.FIRST+1;
	private static final int MENU_ITEM_EDIT_MENU = Menu.FIRST;
	private static final int SHOW_DIALOG_DB_COPYING = 0;
	private static final int SHOW_DIALOG_ADVICE_MAKING = 1;
	public static final int MAX_PERCENTAGE = 105;
//	public static final String INTENT_EXTRA_NAME = "extra";
	private static final String PREFS_LICENCE_NOT_ACCEPTED = "licence";
	private static final int LICENSE_ACTIVITY_CODE = 0;
//	protected static final int LICENSE_ACCEPTED = 1;
//	protected static final int LICENSE_DECLINED = 2;
	
	private static final int MESSAGE_WAIT = 0;
	private static final int MESSAGE_READY = 1;
	
	private boolean advisePossible;
	private int groupId;
	private TextView warningView, protValueView,carboValueView,fatValueView;
	private ListView listView;
	private Button addButton, getAdviceButton, createProfileButton;
	private Cursor menuCursor;
	private MenuAdapter adapter;
	private AdviceHandler handler;
	private RelativeLayout valuesLayout;

//********************************************************************************************	
// on* methods section (Activity lifecycle)
//********************************************************************************************	

	public void onCreate(Bundle b){
		super.onCreate(b);
		setContentView(R.layout.menu_activity);
		
		setTitle( getString(R.string.app_name)+" - "+getString(R.string.my_menu) );
		
		warningView = (TextView)findViewById(R.id.menu_warning_textview);
		listView = (ListView)findViewById(R.id.menu_list);
		addButton = (Button)findViewById(R.id.menu_add_button);
		getAdviceButton = (Button)findViewById(R.id.menu_get_advice_button);
		createProfileButton = (Button)findViewById(R.id.menu_create_profile_button);
		valuesLayout = (RelativeLayout)findViewById(R.id.menu_values_layout);
		protValueView = (TextView)findViewById(R.id.menu_values_prot);
		fatValueView = (TextView)findViewById(R.id.menu_values_fat);
		carboValueView = (TextView)findViewById(R.id.menu_values_carbo);
		
		if(getPreferences(0).getBoolean(PREFS_LICENCE_NOT_ACCEPTED, true)){
			Intent intent = new Intent(getApplicationContext(), LicenceActivity.class);
//			Log.v("menu", "starting licence");
			startActivityForResult(intent, LICENSE_ACTIVITY_CODE);
		}
		
		if( !ProductDataManager.getInstance(getApplicationContext()).databaseExists() )
			copyDatabase();
		
		
		addButton.setOnClickListener(new Button.OnClickListener(){
			public void onClick(View v) {
				Intent intent = new Intent(getApplicationContext(), ProductListActivity.class);
        		startActivity(intent);
			}
		});
		
		getAdviceButton.setOnClickListener(new Button.OnClickListener(){
			public void onClick(View v) {
				if(exceeded()){
					AlertDialog.Builder builder = new AlertDialog.Builder(MenuActivity.this);
					builder.setMessage(getString(R.string.advice_not_available)).
						setPositiveButton(R.string.ok, 
								new DialogInterface.OnClickListener(){
										public void onClick(DialogInterface dialog,	int which) {
										}
						}).show(); 
				}else{
					final Cursor c = ProductDataManager.getInstance(getApplicationContext()).
										getRecommendedGroupsCursor(); 
					SimpleCursorAdapter adapter = new SimpleCursorAdapter(getApplicationContext(),
							R.layout.product_list_item, 
							c,
							new String[]{
								ProductDataProvider.COLUMN_NAMES_GROUPS[ProductDataProvider.GROUP_NAME]
							},
							new int[]{R.id.product_list_item_text});
					AlertDialog.Builder builder = new AlertDialog.Builder(MenuActivity.this);
					builder.setTitle(R.string.select_group_for_advice).
						setAdapter(adapter,	new DialogInterface.OnClickListener(){
								public void onClick(DialogInterface dialog, int which){
									c.moveToPosition(which);
									groupId = c.getInt(0);
									handler = new AdviceHandler();
//									Log.v("MenuActivity","before thread creating");
									Thread t = new Thread(MenuActivity.this);
									t.start();
//									Log.v("MenuActivity","after t.start()");
								}
						}).show();
				}
			}
		});
		listView.setOnCreateContextMenuListener(this);
		listView.setOnItemClickListener(new ListView.OnItemClickListener(){
			public void onItemClick(AdapterView<?> arg0, View v, int arg2,
					long arg3) {
				v.performLongClick();
			}
		});
		
	}
    public void onResume(){
    	super.onResume();
    	updateWindow();
    }

    @Override
    public void onDestroy(){
    	super.onDestroy();
    	if(menuCursor != null)
    		menuCursor.close();
    }

//********************************************************************************************	
// on* methods section 2 (Context & Options menus and dialogs)
//********************************************************************************************	

	
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		AdapterView.AdapterContextMenuInfo info;
        try {
             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        } catch (ClassCastException e) {
            Log.e("AnKFood", "bad menuInfo", e);
            return;
        }

        Cursor cursor = (Cursor)adapter.getItem(info.position);
        if (cursor == null) {
            // For some reason the requested item isn't available, do nothing
            return;
        }
        menu.setHeaderTitle(cursor.getString(0));
        menu.add(0, MENU_ITEM_EDIT_MENU, 0, R.string.edit);
		menu.add(0, MENU_ITEM_DELETE, 0, R.string.delete);
		
		
	}
    public boolean onContextItemSelected(MenuItem item){
    	AdapterView.AdapterContextMenuInfo info;
        try {
            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        } catch (ClassCastException e) {
            Log.e("AnKFood", "bad menuInfo", e);
            return false;
        }

        switch (item.getItemId()) {
            case MENU_ITEM_DELETE: 
                MenuManager.getInstance(getApplicationContext()).deleteMenuItem((int)info.id);
                adapter.changeCursor(MenuManager.getInstance(getApplicationContext()).
                		getMenuCursor());
                if(adapter.getCursor().getCount() == 0){
                	warningView.setText(R.string.menu_is_empty);
                	warningView.setVisibility(TextView.VISIBLE);
                }
                updateWindow();
                return true;
            case MENU_ITEM_EDIT_MENU:
            	Intent intent = new Intent(getApplicationContext(), ProductInfoActivity.class);
            	intent.putExtra(ProductInfoActivity.INTENT_EXTRA_NAME_ITEM_ID, (int)info.id);
            	intent.putExtra(ProductInfoActivity.INTENT_EXTRA_NAME_MODE, 
            			ProductInfoActivity.MODE_EDIT_ITEM);
            	startActivity(intent);
        }
        return false;
    }
    
	public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
//        menu.add(0, MENU_ITEM_VIEW_VALUES, 0, R.string.menu_view_values).
//        	setIcon(android.R.drawable.ic_menu_info_details);
        menu.add(0, MENU_ITEM_CLEAR, 0, R.string.clear_menu).
    		setIcon(android.R.drawable.ic_menu_delete);
        menu.add(0, MENU_ITEM_EDIT_PROFILE, 0, R.string.my_profile).
			setIcon(android.R.drawable.ic_menu_agenda);
        menu.add(0, MENU_ITEM_ABOUT, 0, R.string.about).
			setIcon(android.R.drawable.ic_menu_info_details);
        return true;
    }
    public boolean onOptionsItemSelected(MenuItem item) {
    	Intent intent;
        switch (item.getItemId()) {
        	case MENU_ITEM_CLEAR:
        		if(adapter.getCount() == 0)
        			return true; //there are no items in list, nothing to clear and to ask about
        		AlertDialog.Builder builder = new AlertDialog.Builder(MenuActivity.this);
        		builder.setMessage(getString(R.string.clear_menu_warning))
        			.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener(){
        					public void onClick(DialogInterface dialog,int which) {}
					}).setPositiveButton(R.string.ok,	new DialogInterface.OnClickListener(){
							public void onClick(DialogInterface dialog,	int which) {
								MenuManager.getInstance(getApplicationContext()).clearMenu();
								updateWindow();
							} 
					}).show();
			return true;
        case MENU_ITEM_EDIT_PROFILE:
        	ProfileManager.getInstance(getApplicationContext()).
        			setProfileMode(ProfileManager.PROFILE_MODE_EDIT);
        	intent = new Intent(getApplicationContext(), ProfileActivity.class);
    		startActivity(intent);
    		return true;
        case MENU_ITEM_ABOUT:
        	intent = new Intent(getApplicationContext(), AboutActivity.class);
    		startActivity(intent);
    		return true;
//        case MENU_ITEM_HELP:
//        	intent = new Intent();
//        	intent.setClass(getApplicationContext(), InfoActivity.class);
//        	startActivity(intent);
//        	return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
//	public boolean onKeyDown(int keyCode, KeyEvent event) {
//		if (keyCode == KeyEvent.KEYCODE_BACK) {
////			Intent intent = new Intent();
////			intent.setClass(getApplicationContext(), ProfileChooseActivity.class);
////			startActivity(intent);
//			finish();
//			return true;
//		}
//	    return super.onKeyDown(keyCode, event);
//	}
	
    public Dialog onCreateDialog(int code){
		ProgressDialog dialog = new ProgressDialog(this);
		switch(code){
		case SHOW_DIALOG_DB_COPYING:
			dialog.setCancelable(false);
			dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			dialog.setMessage(getString(R.string.copying_database));
			return dialog;
		case SHOW_DIALOG_ADVICE_MAKING:
			dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			dialog.setMessage(getString(R.string.composing_advice));
			return dialog;
		}
		return null;
	}
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
    	switch(requestCode){
    	case LICENSE_ACTIVITY_CODE:
    		if(resultCode == RESULT_OK){
    			SharedPreferences.Editor editor = getPreferences(0).edit();
//    			Log.v("menu", "license accepted");
    			editor.putBoolean(PREFS_LICENCE_NOT_ACCEPTED, false).commit();
     		}
    		else if(resultCode == RESULT_CANCELED){
//    			Log.v("menu", "license declined");
    			finish();
    		}
    		break;
    	}
    }
    
//********************************************************************************************	
// operation private methods
//********************************************************************************************	
	private void updateWindow(){
		if ( ProfileManager.getInstance(getApplicationContext()).noProfilesExist() ){
			warningView.setText(R.string.profile_not_created);
			warningView.setVisibility(View.VISIBLE);
			createProfileButton.setVisibility(View.VISIBLE);
			createProfileButton.setOnClickListener(new Button.OnClickListener(){
				public void onClick(View v){
					Intent intent = new Intent(getApplicationContext(), ProfileActivity.class);
					intent.putExtra(ProfileActivity.INTENT_EXTRA_NAME, 
							ProfileActivity.PROFILE_MODE_CREATE);
					startActivity(intent);
				}
			});
			addButton.setEnabled(false);
			getAdviceButton.setEnabled(false);
			valuesLayout.setVisibility(View.GONE);
			return;
		}else if( (menuCursor = MenuManager.getInstance(getApplicationContext()).
				getMenuCursor()).getCount() == 0 ){
			warningView.setVisibility(View.VISIBLE);
			warningView.setText(R.string.menu_is_empty);
			createProfileButton.setVisibility(View.INVISIBLE);
			addButton.setEnabled(true);
			getAdviceButton.setEnabled(true);
			valuesLayout.setVisibility(View.GONE);
			return;
		}
		warningView.setVisibility(View.INVISIBLE);
		createProfileButton.setVisibility(View.INVISIBLE);
		adapter = new MenuAdapter(getApplicationContext(), R.layout.menu_list_item, 
				menuCursor);
		listView.setAdapter(adapter);
		addButton.setEnabled(true);
		getAdviceButton.setEnabled(true);
		
		valuesLayout.setVisibility(View.VISIBLE);
		valuesLayout.setBackgroundResource(R.drawable.background_green);
		
		int protPercent = 100*MenuManager.getInstance(getApplicationContext()).getMenuProtEnergy()/
				ProfileManager.getInstance(getApplicationContext()).getProtQuota();
		int fatPercent = 100*MenuManager.getInstance(getApplicationContext()).getMenuFatEnergy()/
				ProfileManager.getInstance(getApplicationContext()).getFatQuota();
		int carboPercent = 100*MenuManager.getInstance(getApplicationContext()).getMenuCarboEnergy()/
				ProfileManager.getInstance(getApplicationContext()).getCarboQuota();
		
		if ( protPercent >= MAX_PERCENTAGE){
			valuesLayout.setBackgroundResource(R.drawable.background_red);
			protValueView.setTextColor(Color.YELLOW);
		}else
			protValueView.setTextColor(Color.WHITE);
		
		if ( fatPercent >= MAX_PERCENTAGE){
			valuesLayout.setBackgroundResource(R.drawable.background_red);
			fatValueView.setTextColor(Color.YELLOW);
		}else
			fatValueView.setTextColor(Color.WHITE);
		
		if ( carboPercent >= MAX_PERCENTAGE){
			valuesLayout.setBackgroundResource(R.drawable.background_red);
			carboValueView.setTextColor(Color.YELLOW);
		}else
			carboValueView.setTextColor(Color.WHITE);
		
		protValueView.setText(getString(R.string.protein)+'\n'+protPercent+'%');
		fatValueView.setText(getString(R.string.fat)+'\n'+fatPercent+'%');
		carboValueView.setText(getString(R.string.carbo)+'\n'+carboPercent+'%');
	}
	
	private boolean exceeded(){
		
		int eatenProtEnergy = MenuManager.getInstance(getApplicationContext()).getMenuProtEnergy();
		int eatenFatEnergy = MenuManager.getInstance(getApplicationContext()).getMenuFatEnergy();
		int eatenCarboEnergy = MenuManager.getInstance(getApplicationContext()).getMenuCarboEnergy();
		
		int protQuota = ProfileManager.getInstance(getApplicationContext()).getProtQuota();
		int fatQuota = ProfileManager.getInstance(getApplicationContext()).getFatQuota();
		int carboQuota = ProfileManager.getInstance(getApplicationContext()).getCarboQuota();
		
		return (eatenProtEnergy >= (protQuota*MAX_PERCENTAGE/100.0) ||
				eatenFatEnergy >= (fatQuota*MAX_PERCENTAGE/100.0) ||
				eatenCarboEnergy >= (carboQuota*MAX_PERCENTAGE/100.0)  );
	}

//********************************************************************************************	
// Advice composing section
//********************************************************************************************	
	
	
	public void run(){
//		Log.v("MenuActivity","in thread - begin");
		Message m;
		m = Message.obtain(handler, MESSAGE_WAIT);
//		Log.v("MenuActivity","before msend WAIT");
		m.sendToTarget();
//		Log.v("MenuActivity","after msend WAIT, before make advice");
		advisePossible = MenuManager.getInstance(getApplicationContext()).makeAndSaveSingleAdvice(groupId);
//		Log.v("MenuActivity","before msend READY, after make advice");
		m = Message.obtain(handler, MESSAGE_READY);
		m.sendToTarget();
//		Log.v("MenuActivity","after msend WAIT");
			
	}
	
	private class AdviceHandler extends Handler{
		
		@Override
		public void handleMessage(Message m){
			switch (m.what){
			
			case MESSAGE_WAIT :
//				Log.v("handler","message wait recived");
				showDialog(SHOW_DIALOG_ADVICE_MAKING);
				break;
			case MESSAGE_READY :
//				Log.v("handler","message ready recived");
				dismissDialog(SHOW_DIALOG_ADVICE_MAKING);
				if(!advisePossible){
//					Log.v("handler","advice not possible");
					AlertDialog.Builder builder = new AlertDialog.Builder(MenuActivity.this);
					builder.setMessage(getString(R.string.no_advice_in_this_group)).
						setNegativeButton(R.string.ok,new DialogInterface.OnClickListener(){
							public void onClick(DialogInterface dialog,int which) {}
						}).
						setTitle(ProductDataManager.getInstance(getApplicationContext()).
								getGroupNameById(groupId)).
						show();
				}
				updateWindow();
				break;
			}
		
		}
	}

	

//********************************************************************************************	
// MenuAdapter section
//********************************************************************************************	

	
	private class MenuAdapter extends SimpleCursorAdapter{

		public MenuAdapter(Context context, int layout, Cursor c){
			super(context, layout, c, new String[]{}, new int[]{});
		}
		
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView text1, text2;
			ViewGroup v;
			if (convertView != null)
				v = (ViewGroup)convertView;
			else
				v = (ViewGroup)LayoutInflater.from(getApplicationContext()).
						inflate(R.layout.menu_list_item, null);
			text1 = (TextView)v.getChildAt(0);
			text2 = (TextView)v.getChildAt(1);
			int id = getIdByPosition(getCursor(), position);
			text1.setText(MenuManager.getInstance(getApplicationContext()).getMenuItemProductName(id));
			text2.setText(MenuManager.getInstance(getApplicationContext()).getMenuItemAmount(id)
					+" x "+MenuManager.getInstance(getApplicationContext()).getMenuItemWeightName(id));
			return v;	
		}
		
		private int getIdByPosition(Cursor c, int pos){
			c.moveToPosition(pos);
			return c.getInt( c.getColumnIndex(MenuProvider.COLUMN_NAMES[MenuProvider.ID]) );
		}
	}
	

	
//********************************************************************************************	
// Database copying section
//********************************************************************************************	
	
	private void copyDatabase(){
		showDialog(SHOW_DIALOG_DB_COPYING);
    	Thread t = new Thread(new DBCopier(getApplicationContext(), new DBCopiyngHandler()));
    	t.start();
	}
	
	private class DBCopier implements Runnable{
		private static final int DB_COPY_SUCCESS_CODE = 0;
		private static final int DB_COPY_FAIL_CODE = 1;
		Context context;
		Handler handler; 
		Message message;
		
		public DBCopier(Context c, Handler h){
			this.context = c;
			this.handler = h;			
		}

		public void run(){
			InputStream input;
			FileOutputStream output;
			ProductDataProvider.DatabaseHelper helper = new ProductDataProvider.DatabaseHelper(context);
			SQLiteDatabase db = helper.getWritableDatabase();
			db.close(); 
			int c;
			byte[] tmp;
			try{
				input = context.getResources().openRawResource(R.raw.products);
				output = new FileOutputStream(ProductDataProvider.DATABASE_LOCATION+
						ProductDataProvider.DATABASE_NAME);
//				//Log.v("DBCopier","flows created. before copying");
				int i=0;
				tmp = new byte[1024];
				while ( (c = input.read(tmp)) != -1 ){
					i++;
					output.write(tmp,0,c);
//					//Log.v("copying",String.valueOf(i));
				}
				//Log.v("DBCopier","finished copying");
				message = Message.obtain(handler, DB_COPY_SUCCESS_CODE);
			}catch(FileNotFoundException e){
				e.printStackTrace();
				//Log.v("DBCopier","Failed to copy - FNF e");
				message = Message.obtain(handler, DB_COPY_FAIL_CODE);
			}catch(IOException e){
				e.printStackTrace();
				//Log.v("DBCopier","Failed to copy - IO e");
				message = Message.obtain(handler, DB_COPY_FAIL_CODE);
			}finally{
				message.sendToTarget();
			}
		}
	}
	
	private class DBCopiyngHandler extends Handler{
		@Override
        public void handleMessage(Message m){
                switch (m.what){
                case DBCopier.DB_COPY_FAIL_CODE :
                	dismissDialog(SHOW_DIALOG_DB_COPYING);
                	AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
                	builder.setMessage(R.string.cant_copy_database).setTitle(R.string.error).
                	setPositiveButton(R.string.ok, new DialogInterface.OnClickListener(){
                		public void onClick(DialogInterface dialog, int which){
                			finish();
                		}
                	}).show();
                	break;
                case DBCopier.DB_COPY_SUCCESS_CODE :
                	dismissDialog(SHOW_DIALOG_DB_COPYING);
                    break;
                }
                
        }
	}
	
}	
